<template>
	<text :class="['v-text', `v-text--${type}`, `v-text--${size}`]" :style="textStyle">
		<slot v-if="!processedText">{{ processedText }}</slot>
		<view v-html="processedText">
			
		</view>
	</text>
</template>

<script setup lang="ts">
import { computed, inject } from 'vue';

const props = defineProps({
	text: {
		type: String,
		default: ''
	},
	type: {
		type: String,
		default: 'default',
		validator: (value: string) => {
			return ['default', 'primary', 'succeed', 'warning', 'delete', 'info'].includes(value);
		}
	},
	size: {
		type: String,
		default: 'medium',
		validator: (value: string) => {
			return ['small', 'medium', 'large'].includes(value);
		}
	},
	color: {
		type: String,
		default: ''
	},
	lineHeight: {
		type: [Number, String],
		default: 1.5
	},
	mode: {
		type: String,
		default: '',
		validator: (value: string) => {
			return ['', 'timestamp', 'amount'].includes(value);
		}
	},
	encrypt: {
		type: String,
		default: '',
		validator: (value: string) => {
			return ['', 'phone', 'name'].includes(value);
		}
	},
	lines: {
		type: [Number, String],
		default: 1
	},
	format: {
		type: String,
		default: ''
	},
	keyword: { type: String, default: '' },
	keywordColor: { type: String, default: '#ff5e5e' }
});

const config = inject<any>('config');

const processedText = computed(() => {
	let result = props.text;

	if (props.mode === 'timestamp' && props.format) {
		// 尝试将文本转换为日期对象
		let date: Date;
		if (/^\d+$/.test(props.text)) {
			// 如果是时间戳（数字）
			date = new Date(parseInt(props.text));
		} else {
			// 如果是日期字符串
			date = new Date(props.text);
		}

		if (!isNaN(date.getTime())) {
			const year = date.getFullYear();
			const month = date.getMonth() + 1;
			const day = date.getDate();
			const hours = date.getHours();
			const minutes = date.getMinutes();
			const seconds = date.getSeconds();

			result = props.format
				.replace('yyyy', year.toString())
				.replace('MM', month.toString().padStart(2, '0'))
				.replace('dd', day.toString().padStart(2, '0'))
				.replace('HH', hours.toString().padStart(2, '0'))
				.replace('mm', minutes.toString().padStart(2, '0'))
				.replace('ss', seconds.toString().padStart(2, '0'));
		}
	} else if (props.mode === 'amount' && props.format) {
		const amount = parseFloat(props.text);
		if (!isNaN(amount)) {
			if (props.format === '$') {
				result = `$${amount.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
			} else if (props.format === '￥') {
				result = `￥${amount.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
			}
		}
	}

	if (props.encrypt === 'phone' && result.length === 11) {
		result = result.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
	} else if (props.encrypt === 'name' && result.length > 1) {
		const firstChar = result.charAt(0);
		result = firstChar + '****' + result.slice(-1);
	}

	// 关键字高亮（最后一步）
	if (props.keyword) {
		const reg = new RegExp(`(${props.keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')})`, 'gi');
		// 先转义再替换
		const escape = (str: string) => str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;');
		result = escape(result).replace(reg, `<span style="color:${props.keywordColor}" class="v-text__keyword">$1</span>`);
	}

	return result;
});

const textStyle = computed(() => {
	const style: Record<string, string | number> = {};
	if (props.color) style.color = props.color;
	if (props.lineHeight) style.lineHeight = typeof props.lineHeight === 'number' ? `${props.lineHeight}` : props.lineHeight;
	if (props.lines) {
		style.webkitLineClamp = typeof props.lines === 'number' ? `${props.lines}` : props.lines;
		style.overflow = 'hidden';
		style.textOverflow = 'ellipsis';
		style.display = '-webkit-box';
		style.webkitBoxOrient = 'vertical';
	}
	return style;
});
</script>

<style lang="scss" scoped>
.v-text {
	font-size: v-bind('config.fontSize.mediumText');
	line-height: 1.5;

	&--default {
		color: v-bind('config.fontColor.text');
	}

	&--primary {
		color: v-bind('config.fontColor.default');
	}

	&--succeed {
		color: v-bind('config.fontColor.succeed');
	}

	&--warn {
		color: v-bind('config.fontColor.warn');
	}

	&--delete {
		color: v-bind('config.fontColor.delete');
	}

	&--info {
		color: v-bind('config.fontColor.info');
	}

	&--small {
		font-size: v-bind('config.fontSize.smallText');
	}

	&--medium {
		font-size: v-bind('config.fontSize.mediumText');
	}

	&--large {
		font-size: v-bind('config.fontSize.largeText');
	}
}
</style>
